home *** CD-ROM | disk | FTP | other *** search
/ Programming a Multiplayer FPS in DirectX / Programming a Multiplayer FPS in DirectX (Companion CD).iso / DirectX / dxsdk_oct2004.exe / dxsdk.exe / Samples / C++ / DirectSound / AmplitudeModulation / amplitudemodulation.cpp next >
Encoding:
C/C++ Source or Header  |  2004-09-27  |  18.5 KB  |  555 lines

  1. //----------------------------------------------------------------------------
  2. // File: AmplitudeModulation.cpp
  3. //
  4. // Desc: AmplitudeModulation sample shows how to create an effect buffer and 
  5. //       adjust amplitude modulation parameters.
  6. //
  7. // Copyright (c) Microsoft Corp. All rights reserved.
  8. //-----------------------------------------------------------------------------
  9. #define STRICT
  10. #include "dxstdafx.h"
  11. #include <commdlg.h>
  12. #include "resource.h"
  13. /*
  14. #include <windows.h>
  15. #include <basetsd.h>
  16. #include <mmsystem.h>
  17. #include <mmreg.h>
  18. #include <dxerr9.h>
  19. #include <dsound.h>
  20. #include <cguid.h>
  21. #include <commctrl.h>
  22. #include <commdlg.h>
  23. #include "resource.h"
  24. #include "DSUtil.h"
  25. #include "DXUtil.h"
  26. */
  27.  
  28.  
  29. //-----------------------------------------------------------------------------
  30. // Function-prototypes
  31. //-----------------------------------------------------------------------------
  32. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg,  WPARAM wParam, LPARAM lParam );
  33. VOID    OnInitDialog( HWND hDlg );
  34. VOID    OnTimer( HWND hDlg );
  35. VOID    OnOpenSoundFile( HWND hDlg );
  36. HRESULT ValidateWaveFile( HWND hDlg, TCHAR* strFileName );
  37. HRESULT OnPlaySound( HWND hDlg );
  38. HRESULT CreateAndFillBuffer( HWND hDlg, DWORD dwCreationFlags );
  39. VOID    OnEffectChanged( HWND hDlg );
  40. VOID    SetBufferOptions( LONG lFrequency, LONG lPan, LONG lVolume );
  41. VOID    EnablePlayUI( HWND hDlg, BOOL bEnable );
  42.  
  43.  
  44.  
  45.  
  46. //-----------------------------------------------------------------------------
  47. // Defines, constants, and global variables
  48. //-----------------------------------------------------------------------------
  49. #define DSFX_GARGLE_RATEHZ_MAX 1000
  50. #define DSFX_GARGLE_RATEHZ_MIN 1
  51.  
  52. TCHAR                       g_strWaveFileName[MAX_PATH];
  53. CSoundManager*              g_pSoundManager     = NULL;
  54. CSound*                     g_pSound            = NULL;
  55. LPDIRECTSOUNDFXGARGLE       g_pIGargle          = NULL;
  56. HINSTANCE                   g_hInst             = NULL;
  57.  
  58.  
  59.  
  60.  
  61. //-----------------------------------------------------------------------------
  62. // Name: WinMain()
  63. // Desc: Entry point for the application.  Since we use a simple dialog for 
  64. //       user interaction we don't need to pump messages.
  65. //-----------------------------------------------------------------------------
  66. INT APIENTRY WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR pCmdLine, INT nCmdShow )
  67. {
  68.     g_hInst = hInst;
  69.  
  70.     CoInitialize( NULL );
  71.  
  72.     // Init the common control dll 
  73.     InitCommonControls();
  74.  
  75.     // Display the main dialog box.
  76.     DialogBox( hInst, MAKEINTRESOURCE(IDD_MAIN), NULL, MainDlgProc );
  77.  
  78.     CoUninitialize();
  79.  
  80.     return TRUE;
  81. }
  82.  
  83.  
  84.  
  85.  
  86. //-----------------------------------------------------------------------------
  87. // Name: MainDlgProc()
  88. // Desc: Handles dialog messages
  89. //-----------------------------------------------------------------------------
  90. INT_PTR CALLBACK MainDlgProc( HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam )
  91. {
  92.     HRESULT hr;
  93.  
  94.     switch( msg ) 
  95.     {
  96.         case WM_COMMAND:
  97.             switch( LOWORD(wParam) )
  98.             {
  99.                 case IDCANCEL:
  100.                     EndDialog( hDlg, IDCANCEL );
  101.                     break;
  102.  
  103.                 case IDC_SOUNDFILE:
  104.                     OnOpenSoundFile( hDlg );
  105.                     break;
  106.  
  107.                 case IDC_PLAY:
  108.                     if( FAILED( hr = OnPlaySound( hDlg ) ) )
  109.                     {
  110.                         DXTRACE_ERR_MSGBOX( TEXT("OnPlaySound"), hr );
  111.                         MessageBox( hDlg, L"Error playing DirectSound buffer."
  112.                                     L"Sample will now exit.", L"DirectSound Sample", 
  113.                                     MB_OK | MB_ICONERROR );
  114.                         EndDialog( hDlg, IDABORT );
  115.                     }
  116.  
  117.                     break;
  118.  
  119.                 case IDC_STOP:
  120.                     SAFE_RELEASE( g_pIGargle );
  121.                     if( g_pSound )
  122.                     {
  123.                         g_pSound->Stop();
  124.                         g_pSound->Reset();
  125.                     }
  126.                     break;
  127.  
  128.                 case IDC_WAVEFORM_TRIANGLE:
  129.                 case IDC_WAVEFORM_SQUARE:
  130.                     OnEffectChanged( hDlg );
  131.                     break;
  132.  
  133.                 default:
  134.                     return FALSE; // Didn't handle message
  135.             }
  136.             break;
  137.  
  138.         case WM_TIMER:
  139.             OnTimer( hDlg );
  140.             break;
  141.  
  142.         case WM_INITDIALOG:
  143.             OnInitDialog( hDlg );
  144.             break;
  145.  
  146.         case WM_NOTIFY:
  147.             OnEffectChanged( hDlg );
  148.             break;
  149.  
  150.         case WM_DESTROY:
  151.             // Cleanup everything
  152.             KillTimer( hDlg, 1 );
  153.             SAFE_RELEASE( g_pIGargle );
  154.             SAFE_DELETE( g_pSound );
  155.             SAFE_DELETE( g_pSoundManager );
  156.             break; 
  157.  
  158.         default:
  159.             return FALSE; // Didn't handle message
  160.     }
  161.  
  162.     return TRUE; // Handled message
  163. }
  164.  
  165.  
  166.  
  167.  
  168. //-----------------------------------------------------------------------------
  169. // Name: OnInitDialog()
  170. // Desc: Initializes the dialogs (sets up UI controls, etc.)
  171. //-----------------------------------------------------------------------------
  172. VOID OnInitDialog( HWND hDlg )
  173. {
  174.     HRESULT hr;
  175.  
  176.     // Load the icon
  177.     HICON hIcon = LoadIcon( g_hInst, MAKEINTRESOURCE( IDR_MAINFRAME ) );
  178.  
  179.     // Create a static IDirectSound in the CSound class.  
  180.     // Set coop level to DSSCL_PRIORITY, and set primary buffer 
  181.     // format to stereo, 22kHz and 16-bit output.
  182.     g_pSoundManager = new CSoundManager();
  183.     if( NULL == g_pSoundManager )
  184.     {
  185.         DXTRACE_ERR_MSGBOX( TEXT("Initialize"), E_OUTOFMEMORY );
  186.         EndDialog( hDlg, IDABORT );
  187.         return;
  188.     }
  189.  
  190.     if( FAILED( hr = g_pSoundManager->Initialize( hDlg, DSSCL_PRIORITY ) ) )
  191.     {
  192.         DXTRACE_ERR_MSGBOX( TEXT("Initialize"), hr );
  193.         MessageBox( hDlg, L"Error initializing DirectSound.  Sample will now exit.", 
  194.                           L"DirectSound Sample", MB_OK | MB_ICONERROR );
  195.         EndDialog( hDlg, IDABORT );
  196.         return;
  197.     }
  198.     
  199.     if( FAILED( hr = g_pSoundManager->SetPrimaryBufferFormat( 2, 22050, 16 ) ) )
  200.     {
  201.         DXTRACE_ERR_MSGBOX( TEXT("SetPrimaryBufferFormat"), hr );
  202.         MessageBox( hDlg, L"Error initializing DirectSound.  Sample will now exit.", 
  203.                           L"DirectSound Sample", MB_OK | MB_ICONERROR );
  204.         EndDialog( hDlg, IDABORT );
  205.         return;
  206.     }
  207.  
  208.     // Set the icon for this dialog.
  209.     PostMessage( hDlg, WM_SETICON, ICON_BIG,   (LPARAM) hIcon );  // Set big icon
  210.     PostMessage( hDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIcon );  // Set small icon
  211.  
  212.     // Create a timer, so we can check for when the soundbuffer is stopped
  213.     SetTimer( hDlg, 0, 250, NULL );
  214.  
  215.     // Get handles to dialog items
  216.     HWND hFreqSlider    = GetDlgItem( hDlg, IDC_FREQUENCY_SLIDER );
  217.  
  218.     // Set UI defaults 
  219.     CheckDlgButton( hDlg, IDC_LOOP_CHECK, BST_CHECKED );
  220.     CheckRadioButton( hDlg, IDC_WAVEFORM_TRIANGLE, IDC_WAVEFORM_TRIANGLE, IDC_WAVEFORM_TRIANGLE );
  221.  
  222.     // Set the range and position of the freq slider from 
  223.     // DSBFREQUENCY_MIN and DSBFREQUENCY_MAX are DirectSound constants
  224.     PostMessage( hFreqSlider, TBM_SETRANGEMAX, TRUE, DSFX_GARGLE_RATEHZ_MAX );
  225.     PostMessage( hFreqSlider, TBM_SETRANGEMIN, TRUE, DSFX_GARGLE_RATEHZ_MIN );
  226.     PostMessage( hFreqSlider, TBM_SETPOS, TRUE, DSFX_GARGLE_RATEHZ_MIN );
  227.  
  228.     // Load default wave file
  229.     TCHAR strFile[MAX_PATH];
  230.     if( GetWindowsDirectory( strFile, MAX_PATH ) == 0 )
  231.         return;
  232.     wcscat( strFile, L"\\media\\ding.wav" );
  233.     
  234.     if( FAILED( hr = ValidateWaveFile( hDlg, strFile ) ) )
  235.     {
  236.         // Set the UI controls
  237.         SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") );
  238.         SetDlgItemText( hDlg, IDC_STATUS, TEXT("No file loaded.") );
  239.     }
  240. }
  241.  
  242.  
  243.  
  244.  
  245. //-----------------------------------------------------------------------------
  246. // Name: OnOpenSoundFile()
  247. // Desc: Called when the user requests to open a sound file
  248. //-----------------------------------------------------------------------------
  249. VOID OnOpenSoundFile( HWND hDlg ) 
  250. {
  251.     static TCHAR strFileName[MAX_PATH] = TEXT("");
  252.     static TCHAR strPath[MAX_PATH] = TEXT("");
  253.  
  254.     // Setup the OPENFILENAME structure
  255.     OPENFILENAME ofn = { sizeof(OPENFILENAME), hDlg, NULL,
  256.                          TEXT("Wave Files\0*.wav\0All Files\0*.*\0\0"), NULL,
  257.                          0, 1, strFileName, MAX_PATH, NULL, 0, strPath,
  258.                          TEXT("Open Sound File"),
  259.                          OFN_FILEMUSTEXIST|OFN_HIDEREADONLY, 0, 0,
  260.                          TEXT(".wav"), 0, NULL, NULL };
  261.  
  262.     // Get the default media path (something like C:\WINDOWS\MEDIA)
  263.     if( '\0' == strPath[0] )
  264.     {
  265.         if( GetWindowsDirectory( strPath, MAX_PATH ) != 0 )
  266.         {
  267.             if( wcscat( &strPath[wcslen(strPath)], TEXT("\\") ) )
  268.                 wcscat( strPath, TEXT("\\") );
  269.             wcscat( strPath, TEXT("MEDIA") );
  270.         }
  271.     }
  272.  
  273.     // Update the UI controls to show the sound as loading a file
  274.     EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), FALSE );
  275.     EnableWindow( GetDlgItem( hDlg, IDC_STOP ), FALSE );
  276.     SetDlgItemText( hDlg, IDC_STATUS, TEXT("Loading file...") );
  277.  
  278.     SAFE_RELEASE( g_pIGargle );
  279.     if( g_pSound )
  280.     {
  281.         g_pSound->Stop();
  282.         g_pSound->Reset();
  283.     }
  284.  
  285.     // Display the OpenFileName dialog. Then, try to load the specified file
  286.     if( TRUE != GetOpenFileName( &ofn ) )
  287.     {
  288.         if( g_pSound )
  289.         {
  290.             EnableWindow( GetDlgItem( hDlg, IDC_PLAY ), TRUE );
  291.             EnableWindow( GetDlgItem( hDlg, IDC_STOP ), TRUE );
  292.         }
  293.  
  294.         SetDlgItemText( hDlg, IDC_STATUS, TEXT("Load aborted.") );
  295.         return;
  296.     }
  297.  
  298.     SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") );
  299.  
  300.     // Make sure wave file is a valid wav file
  301.     ValidateWaveFile( hDlg, strFileName );
  302.  
  303.     // Remember the path for next time
  304.     wcscpy( strPath, strFileName );
  305.     WCHAR* strLastSlash = wcsrchr( strPath, '\\' );
  306.     if( strLastSlash )
  307.         strLastSlash[0] = '\0';
  308. }
  309.  
  310.  
  311.  
  312.  
  313. //-----------------------------------------------------------------------------
  314. // Name: ValidateWaveFile()
  315. // Desc: Open the wave file with the helper 
  316. //       class CWaveFile to make sure it is valid
  317. //-----------------------------------------------------------------------------
  318. HRESULT ValidateWaveFile( HWND hDlg, TCHAR* strFileName )
  319. {
  320.     HRESULT hr;
  321.     CWaveFile waveFile;
  322.  
  323.     if( -1 == GetFileAttributes(strFileName) )
  324.         return E_FAIL;
  325.     
  326.     // Verify the file is small
  327.     HANDLE hFile = CreateFile( strFileName, 0, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
  328.     if( hFile != NULL )
  329.     {
  330.         // If you try to open a 100MB wav file, you could run out of system memory with this
  331.         // sample cause it puts all of it into a large buffer.  If you need to do this, then 
  332.         // see the "StreamData" sample to stream the data from the file into a sound buffer.
  333.         DWORD dwFileSizeHigh = 0;
  334.         DWORD dwFileSize = GetFileSize( hFile, &dwFileSizeHigh );
  335.         CloseHandle( hFile );
  336.  
  337.         if( dwFileSizeHigh != 0 || dwFileSize > 1000000 )
  338.         {
  339.             waveFile.Close();
  340.             SetDlgItemText( hDlg, IDC_STATUS, TEXT("File too large.  You should stream large files.") );
  341.             return E_FAIL;
  342.         }
  343.     }
  344.  
  345.     // Load the wave file
  346.     if( FAILED( hr = waveFile.Open( strFileName, NULL, WAVEFILE_READ ) ) )
  347.     {        
  348.         waveFile.Close();
  349.         SetDlgItemText( hDlg, IDC_STATUS, TEXT("Bad wave file.") );
  350.         return DXTRACE_ERR_MSGBOX( TEXT("Open"), hr );
  351.     }
  352.     else // The load call succeeded
  353.     {
  354.         WAVEFORMATEX* pwfx = waveFile.GetFormat();
  355.         if( pwfx->wFormatTag != WAVE_FORMAT_PCM )
  356.         {
  357.             // Sound must be PCM when using DSBCAPS_CTRLFX            
  358.             SAFE_RELEASE( g_pIGargle );
  359.             SAFE_DELETE( g_pSound );
  360.             SetDlgItemText( hDlg, IDC_STATUS, TEXT("Wave file must be PCM for effects control.") );
  361.             SetDlgItemText( hDlg, IDC_FILENAME, TEXT("") );
  362.             return S_FALSE;
  363.         }
  364.   
  365.         // Update the UI controls to show the sound as the file is loaded
  366.         waveFile.Close();
  367.  
  368.         EnablePlayUI( hDlg, TRUE );
  369.         SetDlgItemText( hDlg, IDC_FILENAME, strFileName );
  370.         SetDlgItemText( hDlg, IDC_STATUS, TEXT("File loaded.") );
  371.         wcscpy( g_strWaveFileName, strFileName );
  372.         return S_OK;
  373.     }
  374. }
  375.  
  376.  
  377.  
  378.  
  379. //-----------------------------------------------------------------------------
  380. // Name: OnPlaySound()
  381. // Desc: User hit the "Play" button
  382. //-----------------------------------------------------------------------------
  383. HRESULT OnPlaySound( HWND hDlg ) 
  384. {
  385.     HRESULT                 hr;
  386.     DWORD                   dwCreationFlags;
  387.     DWORD                   dwResults;
  388.  
  389.     LPDIRECTSOUNDBUFFER  pDSB = NULL;
  390.     LPDIRECTSOUNDBUFFER8 pDSB8 = NULL;
  391.  
  392.     BOOL bLooped        = ( IsDlgButtonChecked( hDlg, IDC_LOOP_CHECK )     == BST_CHECKED );
  393.  
  394.     // We would only use CTRLFX control on dsound buffer
  395.     dwCreationFlags = DSBCAPS_CTRLFX;
  396.  
  397.     // Free any previous sound and FXs
  398.     SAFE_RELEASE( g_pIGargle );
  399.     SAFE_DELETE( g_pSound );
  400.  
  401.     // Since the user can change the focus before the sound is played, 
  402.     // we need to create the sound buffer every time the play button is pressed 
  403.  
  404.     // Load the wave file into a DirectSound buffer
  405.     if( FAILED( hr = g_pSoundManager->Create( &g_pSound, g_strWaveFileName, dwCreationFlags, GUID_NULL ) ) )
  406.     {
  407.         // Not a critical failure, so just update the status
  408.         DXTRACE_ERR( TEXT("Create"), hr );
  409.         if( hr == DSERR_BUFFERTOOSMALL )
  410.         {
  411.             // DSERR_BUFFERTOOSMALL will be returned if the buffer is
  412.             // less than DSBSIZE_FX_MIN (100ms) and the buffer is created
  413.             // with DSBCAPS_CTRLFX.                           
  414.             SetDlgItemText( hDlg, IDC_STATUS, TEXT("Wave file is too short (less than 100ms) for effect processing.") );
  415.         }
  416.         else
  417.         {
  418.             SetDlgItemText( hDlg, IDC_STATUS, TEXT("Could not create sound buffer.") );
  419.         }
  420.         
  421.         return S_FALSE; 
  422.     }
  423.  
  424.     // Query IDirectSoundBuffer8 interface
  425.     pDSB = g_pSound->GetBuffer( 0 );
  426.     if( FAILED( hr = pDSB->QueryInterface( IID_IDirectSoundBuffer8, (LPVOID*) &pDSB8 ) ) )
  427.         return DXTRACE_ERR_MSGBOX( TEXT("QueryInterface"), hr );
  428.  
  429.     // Set gargle effect on the IDirectSoundBuffer8
  430.     DSEFFECTDESC dsed;
  431.     ZeroMemory( &dsed, sizeof(DSEFFECTDESC) );
  432.     dsed.dwSize       = sizeof(DSEFFECTDESC);
  433.     dsed.dwFlags      = 0;
  434.     dsed.guidDSFXClass = GUID_DSFX_STANDARD_GARGLE;
  435.  
  436.     if( FAILED( hr = pDSB8->SetFX( 1, &dsed, &dwResults ) ) )
  437.     {
  438.         // Not a critical failure, so just update the status
  439.         DXTRACE_ERR_MSGBOX( TEXT("SetFX"), hr );
  440.         SetDlgItemText( hDlg, IDC_STATUS, TEXT("Could not set gargle effect.") );
  441.         return S_FALSE;
  442.     }
  443.  
  444.     // Get gargle effect friendly interface
  445.     if( FAILED( hr = pDSB8->GetObjectInPath( GUID_DSFX_STANDARD_GARGLE, 0, 
  446.                                              IID_IDirectSoundFXGargle, 
  447.                                              (LPVOID*) &g_pIGargle ) ) )
  448.         return DXTRACE_ERR_MSGBOX( TEXT("GetObjectInPath"), hr );
  449.  
  450.     // Cleanup
  451.     SAFE_RELEASE( pDSB8 );
  452.  
  453.     // Set the buffer options to what the sliders are set to
  454.     OnEffectChanged( hDlg );
  455.  
  456.     // Play the sound
  457.     DWORD dwLooped = bLooped ? DSBPLAY_LOOPING : 0L;
  458.     if( FAILED( hr = g_pSound->Play( 0, dwLooped ) ) )
  459.         return DXTRACE_ERR_MSGBOX( TEXT("Play"), hr );
  460.  
  461.     // Update the UI controls to show the sound as playing
  462.     EnablePlayUI( hDlg, FALSE );
  463.     SetDlgItemText( hDlg, IDC_STATUS, TEXT("Sound playing.") );
  464.  
  465.     return S_OK;
  466. }
  467.  
  468.  
  469.  
  470.  
  471. //-----------------------------------------------------------------------------
  472. // Name: OnTimer()
  473. // Desc: When we think the sound is playing this periodically checks to see if 
  474. //       the sound has stopped.  If it has then updates the dialog.
  475. //-----------------------------------------------------------------------------
  476. VOID OnTimer( HWND hDlg ) 
  477. {
  478.     if( IsWindowEnabled( GetDlgItem( hDlg, IDC_STOP ) ) )
  479.     {
  480.         // We think the sound is playing, so see if it has stopped yet.
  481.         if( !g_pSound->IsSoundPlaying() ) 
  482.         {
  483.             // Update the UI controls to show the sound as stopped
  484.             EnablePlayUI( hDlg, TRUE );
  485.             SetDlgItemText( hDlg, IDC_STATUS, TEXT("Sound stopped.") );
  486.         }
  487.     }
  488. }
  489.  
  490.  
  491.  
  492.  
  493. //-----------------------------------------------------------------------------
  494. // Name: OnEffectChanged()  
  495. // Desc: Called when the UI prompted an effect change
  496. //-----------------------------------------------------------------------------
  497. VOID OnEffectChanged( HWND hDlg )
  498. {
  499.     DSFXGargle dsfxGargle;
  500.  
  501.     // Get handles to dialog items
  502.     HWND hFreqSlider = GetDlgItem( hDlg, IDC_FREQUENCY_SLIDER );
  503.  
  504.     // Get the position of the sliders
  505.     dsfxGargle.dwRateHz = (DWORD)SendMessage( hFreqSlider, TBM_GETPOS, 0, 0 );
  506.  
  507.     // Update UI
  508.     TCHAR strBuffer[10];
  509.     wsprintf( strBuffer, TEXT("%ld"), dsfxGargle.dwRateHz );
  510.     SetDlgItemText( hDlg, IDC_FREQUENCY, strBuffer );
  511.  
  512.     // Get wave form
  513.     if( IsDlgButtonChecked( hDlg, IDC_WAVEFORM_SQUARE ) == BST_CHECKED )
  514.         dsfxGargle.dwWaveShape = DSFXGARGLE_WAVE_SQUARE;
  515.     else 
  516.         dsfxGargle.dwWaveShape = DSFXGARGLE_WAVE_TRIANGLE;
  517.  
  518.     // Set the options in the DirectSound buffer
  519.     if( g_pSound && g_pIGargle )
  520.     {
  521.         g_pIGargle->SetAllParameters( &dsfxGargle );
  522.     }
  523. }
  524.  
  525.  
  526.  
  527.  
  528. //-----------------------------------------------------------------------------
  529. // Name: EnablePlayUI()
  530. // Desc: Enables or disables the Play UI controls 
  531. //-----------------------------------------------------------------------------
  532. VOID EnablePlayUI( HWND hDlg, BOOL bEnable )
  533. {
  534.     if( bEnable )
  535.     {
  536.         EnableWindow( GetDlgItem( hDlg, IDC_LOOP_CHECK      ), TRUE );
  537.         EnableWindow( GetDlgItem( hDlg, IDC_PLAY            ), TRUE );
  538.         EnableWindow( GetDlgItem( hDlg, IDC_STOP            ), FALSE );
  539.         SetFocus(     GetDlgItem( hDlg, IDC_PLAY ) );
  540.     }
  541.     else
  542.     {
  543.         EnableWindow( GetDlgItem( hDlg, IDC_LOOP_CHECK      ), FALSE );
  544.         EnableWindow( GetDlgItem( hDlg, IDC_PLAY            ), FALSE );
  545.         EnableWindow( GetDlgItem( hDlg, IDC_STOP            ), TRUE );
  546.         SetFocus(     GetDlgItem( hDlg, IDC_STOP ) );
  547.     }
  548. }
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.